package com.ztesoft.book.api.controller.sys;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.SetBucketCORSRequest;
import com.ztesoft.book.common.utils.Result;
import com.ztesoft.book.common.utils.aliyunoss.AliyunOssUtils;
import com.ztesoft.book.common.utils.exception.ServiceException;
import com.ztesoft.book.core.aliyun.oss.dto.STSResponse;
import com.ztesoft.book.core.aliyun.oss.service.STSService;
import com.ztesoft.book.core.sys.sysfile.dto.SysFileDTO;
import com.ztesoft.book.core.sys.sysfile.service.SysFileService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;

/**
 * @Description 文件上传
 * @Author YangFan
 * @Date 2021-07-15 14:42
 */
@Slf4j
@RestController
@RequestMapping("/sys/sysFile")
public class SysFileController {

    @Resource
    private STSService stsService;

    @Value("${book.oss.accessKeyId}")
    private String accessKeyId;
    @Value("${book.oss.accessKeySecret}")
    private String accessKeySecret;
    @Value("${book.oss.bucket}")
    private String bucket;
    @Value("${book.oss.endPoint}")
    private String endPoint;
    @Value("${book.oss.region}")
    private String region;
    @Value("${book.oss.arm}")
    private String roleArn;

    @Resource
    private SysFileService sysFileService;


    /**
     * getTemOssAuth
     *
     * @return Result
     */
    @PostMapping("/getTemOssAuth")
    public @ResponseBody
    Result getTemOssAuth() {
        try {
            STSResponse stsResponse = stsService.getSTSCredentials(accessKeyId, accessKeySecret, roleArn,
                    "ossTem" + System.currentTimeMillis());
            stsResponse.setBucket(bucket);
            stsResponse.setEndPoint(endPoint);
            stsResponse.setRegion(region);
            String head = "https://" + bucket + "." + endPoint.replace("https://", "");
            stsResponse.setHead(head);
            return Result.success(stsResponse);
        }
        catch (Exception e) {
            log.error("获取临时权限失败", e);
            return Result.error("获取临时权限失败");
        }
    }


    /**
     * 文件直传oss后调用的接口,保存文件到sys_file
     */
    @PostMapping("/saveOssFile")
    @ApiOperation(value = "文件直传oss后调用的接口,保存文件到sys_file")
    public Result saveOssFile(@RequestBody SysFileDTO dto) {
        try {
            SysFileDTO sysFileDTO = sysFileService.saveOssFile(dto);
            return Result.success(sysFileDTO);
        }
        catch (Exception e) {
            log.error("文件上传失败", e);
            return Result.error("操作失败！");
        }
    }


    /**
     * 方法功能描述:
     * < 通用文件上传接口 >
     *
     * @param request      【参数 1 注释说明】
     * @param businessName 【参数 2 业务名称】
     * @param file         【参数 3 MultipartFile文件】
     * @return Result
     * @author YangFan
     * @date 2021-07-16 11:20
     */
    @PostMapping("/uploadOssFile")
    public @ResponseBody
    Result uploadOssFile(HttpServletRequest request, @RequestParam String businessName, MultipartFile file) {
        try {
            String path = AliyunOssUtils.uploadFileInputSteam(businessName, file);
            SysFileDTO dto = new SysFileDTO();
            dto.setName(file.getOriginalFilename());
            dto.setType(businessName);
            dto.setSize((int) file.getSize());
            dto.setPath(path);
            sysFileService.saveOssFile(dto);
            return Result.success(dto);
        }
        catch (ServiceException e) {
            return Result.error(e.getMsg());
        }
    }


    @GetMapping("/getCorsRules")
    public Result getCorsRules() {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);

        ArrayList<SetBucketCORSRequest.CORSRule> corsRules;
        // 获取跨域资源共享规则列表。
        corsRules = (ArrayList<SetBucketCORSRequest.CORSRule>) ossClient.getBucketCORSRules(bucket);
        for (SetBucketCORSRequest.CORSRule rule : corsRules) {
            for (String allowedOrigin1 : rule.getAllowedOrigins()) {
                // 获取允许的跨域请求源。
                log.info(allowedOrigin1);
            }
            for (String allowedMethod1 : rule.getAllowedMethods()) {
                // 获取允许的跨域请求方法。
                log.info(allowedMethod1);
            }
            if (rule.getAllowedHeaders()
                    .size() > 0) {
                for (String allowedHeader1 : rule.getAllowedHeaders()) {
                    // 获取允许的头部列表。
                    log.info(allowedHeader1);
                }
            }
            if (rule.getExposeHeaders()
                    .size() > 0) {
                for (String exposeHeader : rule.getExposeHeaders()) {
                    // 获取允许的头部。
                    log.info(exposeHeader);
                }
            }
            if (null != rule.getMaxAgeSeconds()) {
                log.info(rule.getMaxAgeSeconds() + "");
            }
        }
        // 关闭OSSClient。
        ossClient.shutdown();
        return Result.success();
    }


    @GetMapping("/setCorsRules")
    public Result setCorsRules() {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
        SetBucketCORSRequest request = new SetBucketCORSRequest(bucket);
        // 跨域资源共享规则的容器，每个存储空间最多允许10条规则。
        ArrayList<SetBucketCORSRequest.CORSRule> putCorsRules = new ArrayList<SetBucketCORSRequest.CORSRule>();
        SetBucketCORSRequest.CORSRule corRule = new SetBucketCORSRequest.CORSRule();
        ArrayList<String> allowedOrigin = new ArrayList<String>();
        // 指定允许跨域请求的来源。
        allowedOrigin.add("*");

        ArrayList<String> allowedMethod = new ArrayList<String>();
        // 指定允许的跨域请求方法(GET/PUT/DELETE/POST/HEAD)。
        allowedMethod.add("GET");
        allowedMethod.add("DELETE");
        allowedMethod.add("PUT");
        allowedMethod.add("POST");
        allowedMethod.add("HEAD");

        ArrayList<String> allowedHeader = new ArrayList<String>();
        // 是否允许预取指令（OPTIONS）中Access-Control-Request-Headers头中指定的Header。
        allowedHeader.add("*");

        ArrayList<String> exposedHeader = new ArrayList<String>();
        // 指定允许用户从应用程序中访问的响应头。
        exposedHeader.add("ETag");
        exposedHeader.add("x-oss-request-id");
        exposedHeader.add("x-oss-version-id");
        // AllowedOrigins和AllowedMethods最多支持一个星号（*）通配符。星号（*）表示允许所有的域来源或者操作。
        corRule.setAllowedMethods(allowedMethod);
        corRule.setAllowedOrigins(allowedOrigin);
        // AllowedHeaders和ExposeHeaders不支持通配符。
        corRule.setAllowedHeaders(allowedHeader);
        corRule.setExposeHeaders(exposedHeader);
        // 指定浏览器对特定资源的预取（OPTIONS）请求返回结果的缓存时间，单位为秒。
        corRule.setMaxAgeSeconds(10);

        // 最多允许10条规则。
        putCorsRules.add(corRule);
        // 已存在的规则将被覆盖。
        request.setCorsRules(putCorsRules);
        ossClient.setBucketCORS(request);

        // 关闭OSSClient。
        ossClient.shutdown();
        return Result.success();
    }


}



